package com.whq.controller;

import com.alibaba.druid.wall.violation.ErrorCode;
import com.mysql.jdbc.StringUtils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import com.whq.wechat.WechatPayOrderVo;
import com.whq.wechat.utils.Signature;
import com.whq.wechat.utils.XMLParser;
import com.whq.wechatpay.WechatPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;


/**
 * Created by lenovo on 2018/4/10.
 */
@RestController
@RequestMapping("/api/v1/wechat")
@Api(value = "微信支付", description = "扫码支付", tags = "微信支付")
public class WechatPayController {

    Logger logger = LoggerFactory.getLogger(WechatPayController.class);


    @Autowired
    WechatPayService wechatPayService;


    @RequestMapping(method = RequestMethod.GET, value = "/unifiedorder")
    public ResponseEntity<?> unifiedorder(WechatPayOrderVo wechatPayOrder, HttpServletRequest request){
        try{

            //1、验证orderNo是否为空
            if(StringUtils.isNullOrEmpty(wechatPayOrder.getOrderNo())){
                return new ResponseEntity<String>("订单号不为空",HttpStatus.INTERNAL_SERVER_ERROR);
            }
            //2、验证订单金额否为空
            if(wechatPayOrder.getTotal()==null||wechatPayOrder.getTotal().equals(0)){
                return new ResponseEntity<String>("订单金额必须大于0",HttpStatus.INTERNAL_SERVER_ERROR);
            }
//            CustomerOrder customerOrder = customerOrderService.findCustomerOrderById(wechatPayOrder.getOrderNo());
//            if (customerOrder==null){
//                return ResponseUtil.error (ErrorCode.APP_GENERAL_ERR_CODE, "订单号不存在");
//            }
            //调用统一下单接口生成 二维码
           // String codeUrl = this.makeWechatPay(wechatPayOrder, request);
            String codeUrl =  wechatPayService.makeWechatPay(wechatPayOrder);
            //    此出讓前端生成二維碼
           //String code_img_url = createCodeImg(codeUrl);
            String code_img_url = wechatPayService.createCodeImg(codeUrl);
            wechatPayOrder.setCode_url(code_img_url);
            logger.info("codeUrl>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+codeUrl);
           // return ResponseUtil.success (codeUrl);
            return new ResponseEntity<WechatPayOrderVo>(wechatPayOrder,HttpStatus.OK);

        } catch (Exception e) {
            return new ResponseEntity<String>("服务器异常...",HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     *  微信支付异步通知处理接口
     * @param request
     * @param response
     * @return
     * @throws IOException
     */

    @ApiOperation(value = "回调")
    @RequestMapping(value ="/weipayCallBack",method = RequestMethod.GET)
    public void weipayCallBack(HttpServletRequest request,HttpServletResponse response) throws IOException {
        logger.info("**************************微信支付异步回调通知开始***********************");
        System.out.println("收到微信异步通知。。。");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String resultStr  = new String(outSteam.toByteArray(),"utf-8");
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            resultMap = XMLParser.getMapFromXML(resultStr);
            //*//*商户订单号*//*
            String out_trade_no = (String) resultMap.get("out_trade_no");
           // *//*业务结果*//*
            String return_code = (String) resultMap.get("return_code");
           // *//*订单金额*//*
            String total_fee = (String) resultMap.get("total_fee");
           // *//*付款银行*//*
            String bank = (String) resultMap.get("bank_type");
           // *//*微信支付订单号*//*
            String transaction_id = (String) resultMap.get("transaction_id");
            Integer fee = Integer.decode(total_fee)/100;
            //签名验证
            boolean valid = Signature.checkIsSignValidFromResponseString(resultStr);

            //业务逻辑做处理,订单号是否一致，订单金额

            if(return_code.equals("SUCCESS") && valid){
                //处理订单后续业务
                logger.info("************微信支付异步回调通知支付成功"+resultMap);
            }else{
                try {
                    // 處理業務邏輯
                  //  chargeOrderLogService.updateChargeOrderLogFail(log);
                } catch (Exception e) {
                    logger.info("************微信支付异步回调插入日志异常"+e.getMessage());
                }
                logger.info("************微信支付异步回调通知支付失败"+resultMap);

            }
        } catch (Exception e){
            logger.info("************微信支付异步回调通知支付失败"+resultMap);

        }
        //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.[一定不能return_msg回去，不然会继续回调的]
        String success = "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
        response.getOutputStream().write(new String(success).getBytes());
        logger.info("**************************微信支付异步回调通知结束***********************");
    }



    /**
     * 构造微信统一下单接口 返回数据
     * @Description:TODO
     * @return String
     */
    /*private String makeWechatPay(WechatPayOrderVo chargeOrder, HttpServletRequest request){
        logger.info("进去系统统一下单接口");
        String code_url = null;
        try {
            // 签名随机字符串，由于微信里面的坑太多，所以我们所有的签名字符串和时间戳最好公用，不然真的会蒙圈的
            String weiPaySignStr = WechatUrl.getRandomStringByLength(20);
            // 签名用时间戳 秒
            String timestamp = (System.currentTimeMillis()/1000) + "";
            // 统一下单签名参数哈希表
            // 统一下单的body,就是商品详情，要是传中文记得newString(body.getBytes("ISO8859-1"))，不然JS签名失败，
            // 但是即使这样,支付成功后微信给你发的支付凭证中商品详情还是乱码显示，所以传英文吧，这坑懒得去填
            String body = "langdeng WeChat Order Pay";
            Map<String, Object> prepaySignParam = new HashMap<String, Object>();
            prepaySignParam.put("appid",  Constant.APPID);
            prepaySignParam.put("mch_id",  Constant.MCHID);
            prepaySignParam.put("body", body);
            prepaySignParam.put("nonce_str", weiPaySignStr);
            // 微信异步通知地址，在这里处理后续订单逻辑
            prepaySignParam.put("notify_url",
                    Constant.DOMAIN+"wechat/weipayCallBack");
            prepaySignParam.put("out_trade_no", chargeOrder.getOrderNo()); //获取系统订单编号
            prepaySignParam.put("spbill_create_ip", "123.12.12.123");// 用户IP地址
            //测试先改为0.01
            // 单位分
//            prepaySignParam.put("total_fee",chargeOrder.getTotal().multiply(new BigDecimal(100)));
            prepaySignParam.put("total_fee","1");

            //正式
           // prepaySignParam.put("total_fee", chargeOrder.getTotal().multiply(new BigDecimal(100)).intValue());
            prepaySignParam.put("trade_type", "NATIVE");

            // 构造微信预支付订单
            WeiChatPreAppOrder weiChatPreOrder = new WeiChatPreAppOrder();
            weiChatPreOrder.setAppid(Constant.APPID);
            weiChatPreOrder.setMch_id(Constant.MCHID);
            weiChatPreOrder.setBody(body);
            weiChatPreOrder.setNonce_str(weiPaySignStr);
            weiChatPreOrder.setNotify_url(Constant.DOMAIN+"wechat/weipayCallBack");
            weiChatPreOrder.setOut_trade_no(chargeOrder.getOrderNo());// 系统订单号
            weiChatPreOrder.setSpbill_create_ip("123.12.12.123");
            //测试先改为0.01
            weiChatPreOrder.setTotal_fee(1);
            //正式
            //weiChatPreOrder.setTotal_fee(chargeOrder.getTotal().multiply(new BigDecimal(100)).intValue());
            weiChatPreOrder.setTrade_type("NATIVE");
            // 计算统一下单签名参数计算预支付订单的MD5签名
            logger.info("微信的key"+Constant.WECHAT_KEY);
            weiChatPreOrder.setSign(Signature.getSign(prepaySignParam));
            // 生成XML订单
            XStream stream = new XStream(new Xpp3Driver(new NoNameCoder()));
            stream.processAnnotations(weiChatPreOrder.getClass());
            String xmlOrder = stream.toXML(weiChatPreOrder);
            logger.info("统一下单接口的xml"+xmlOrder);
            // 通过微信下单接口获取code_url
            code_url = WechatUrl.getCodeUrl(xmlOrder);
            logger.info("统一下单接口的code_url"+code_url);

        } catch (Exception e) {
            logger.info("app获取支付所需参数错误"+e.getMessage());
        }
        return code_url;
    }*/


   /* private  String  createCodeImg(String url) throws Exception {
        String codeUrl = QRCodeUtil.encode(url, "", Constant.CODE_IMG_PATH, false);
        return Constant.IMG_URL+codeUrl;
    }*/

    public static void main(String[] args) throws IOException {

//        WeiChatPreAppOrder weiChatPreOrder = new WeiChatPreAppOrder();
//        weiChatPreOrder.setAppid(Constant.APPID);
//        weiChatPreOrder.setMch_id(Constant.MCHID);
//        weiChatPreOrder.setBody("111");
//        weiChatPreOrder.setNonce_str("123");
//        weiChatPreOrder.setNotify_url(Constant.DOMAIN+"wechat/wechatPay/weipayCallBack.do");
//        weiChatPreOrder.setOut_trade_no("123");// 系统订单号
//        weiChatPreOrder.setSpbill_create_ip("123");
//        //测试先改为0.01
//        weiChatPreOrder.setTotal_fee(1);
//        //正式
//        //weiChatPreOrder.setTotal_fee(chargeOrder.getTotal().multiply(new BigDecimal(100)).intValue());
//        weiChatPreOrder.setTrade_type("NATIVE");
//        // 计算统一下单签名参数计算预支付订单的MD5签名
//        System.out.println("微信的key"+Constant.WECHAT_KEY);
//        // 生成XML订单
//        XStream stream = new XStream(new Xpp3Driver(new NoNameCoder()));
//        stream.processAnnotations(weiChatPreOrder.getClass());
//        String xmlOrder = stream.toXML(weiChatPreOrder);
//        System.out.println("统一下单接口的xml"+xmlOrder);
}
}
